package com.pattern.create.singleton.IoDH;

/***
 * 编
 * 译并运行上述代码， 运行结果为： true， 即创建的单例对象s1和s2为同一对象。 由于静态单
 * 例对象没有作为Singleton的成员变量直接实例化， 因此类加载时不会实例化Singleton， 第一次
 * 调用getInstance()时将加载内部类HolderClass， 在该内部类中定义了一个static类型的变量
 * instance， 此时会首先初始化这个成员变量， 由Java虚拟机来保证其线程安全性， 确保该成员
 * 变量只能初始化一次。 由于getInstance()方法没有任何线程锁定， 因此其性能不会造成任何影
 * 响。
 * 通过使用IoDH， 我们既可以实现延迟加载， 又可以保证线程安全， 不影响系统性能， 不失为
 * 一种最好的Java语言单例模式实现方式（ 其缺点是与编程语言本身的特性相关， 很多面向对象
 * 语言不支持IoDH） 。
 *
 *
 *
 * 3.6 单例模式总结
 * 单例模式作为一种目标明确、 结构简单、 理解容易的设计模式， 在软件开发中使用频率相当
 * 高， 在很多应用软件和框架中都得以广泛应用。
 * 1.主要优点
 * 单例模式的主要优点如下：
 * (1) 单例模式提供了对唯一实例的受控访问。 因为单例类封装了它的唯一实例， 所以它可以严
 * 格控制客户怎样以及何时访问它。
 * (2) 由于在系统内存中只存在一个对象， 因此可以节约系统资源， 对于一些需要频繁创建和销
 * 毁的对象单例模式无疑可以提高系统的性能。
 * (3) 允许可变数目的实例。 基于单例模式我们可以进行扩展， 使用与单例控制相似的方法来获
 * 得指定个数的对象实例， 既节省系统资源， 又解决了单例单例对象共享过多有损性能的问
 * 题。
 * 2.主要缺点
 * 单例模式的主要缺点如下：
 * (1) 由于单例模式中没有抽象层， 因此单例类的扩展有很大的困难。
 * (2) 单例类的职责过重， 在一定程度上违背了“单一职责原则”。 因为单例类既充当了工厂角
 * 色， 提供了工厂方法， 同时又充当了产品角色， 包含一些业务方法， 将产品的创建和产品的
 * 本身的功能融合到一起。
 * (3) 现在很多面向对象语言(如Java、 C#)的运行环境都提供了自动垃圾回收的技术， 因此， 如
 * 果实例化的共享对象长时间不被利用， 系统会认为它是垃圾， 会自动销毁并回收资源， 下次
 * 利用时又将重新实例化， 这将导致共享的单例对象状态的丢失。
 * 3.适用场景
 * 在以下情况下可以考虑使用单例模式：
 * (1) 系统只需要一个实例对象， 如系统要求提供一个唯一的序列号生成器或资源管理器， 或者
 * 需要考虑资源消耗太大而只允许创建一个对象。
 * (2) 客户调用类的单个实例只允许使用一个公共访问点， 除了该公共访问点， 不能通过其他途
 * 径访问该实例。
 * 思考
 * 如何对单例模式进行改造， 使得系统中某个类的对象可以存在有限多个， 例如两例或三例？
 * 【注： 改造之后的类可称之为多例类。 】
 */
public class Singleton {
    private Singleton() {
    }

    public static Singleton getInstance() {
        return HolderClass.instance;
    }

    private static class HolderClass {
        private final static Singleton instance = new Singleton();
    }

}
